#include "fd_epoll.h"
#include <iostream>

using namespace std;
using namespace NetKit;

Epoll::Epoll(int maxFd)
{
	m_epfd = epoll_create(maxFd);
	m_iEventNum = 0;
	m_iEventArraySize = 1024;	
	m_pEvents = new struct epoll_event[m_iEventArraySize];
}

Epoll::~Epoll()
{
	delete[] m_pEvents;
}

void Epoll::AddReadEvent(int fd)
{
	if ( m_iEventNum >= m_iEventArraySize )
		Grow(256);
	//cout << "add fd : " << fd << endl;
	m_ev.data.fd = fd;
	m_ev.events = EPOLLIN;
	epoll_ctl(m_epfd, EPOLL_CTL_ADD, fd, &m_ev);
	++m_iEventNum;
}

void Epoll::AddWriteEvent(int fd)
{
	if ( m_iEventNum >= m_iEventArraySize )
		Grow(256);
	//cout << "add fd : " << fd << endl;
	m_ev.data.fd = fd;
	m_ev.events = EPOLLOUT;
	epoll_ctl(m_epfd, EPOLL_CTL_ADD, fd, &m_ev);
	++m_iEventNum;
}

void Epoll::ModWriteEvent(int fd)
{
	//cout << "mod write fd : " << fd << endl;
	m_ev.data.fd = fd;
	m_ev.events = EPOLLOUT;
	epoll_ctl(m_epfd, EPOLL_CTL_MOD, fd, &m_ev);	
}

void Epoll::ModReadEvent(int fd)
{
	//cout << "mod read fd : " << fd << endl;
	m_ev.data.fd = fd;
	m_ev.events = EPOLLIN;
	epoll_ctl(m_epfd, EPOLL_CTL_MOD, fd, &m_ev);	
}

void Epoll::ModReadWriteEvent(int fd)
{
	//cout << "mod read fd : " << fd << endl;
	m_ev.data.fd = fd;
	m_ev.events = EPOLLIN|EPOLLOUT;
	epoll_ctl(m_epfd, EPOLL_CTL_MOD, fd, &m_ev);	
}

void Epoll::DelEvent(int fd)
{
	m_ev.data.fd = fd;
	epoll_ctl(m_epfd, EPOLL_CTL_DEL, fd, &m_ev);	
	--m_iEventNum;
}

int Epoll::EpollWait(int timeout_ms)
{
	return epoll_wait(m_epfd, m_pEvents, m_iEventNum, timeout_ms);
}
	
void Epoll::Grow(int size)
{
	struct epoll_event* pNew = new struct epoll_event[m_iEventArraySize + size];
	delete[] m_pEvents;
	m_pEvents = pNew;
	m_iEventArraySize += size;	
}	

void Epoll::GetFdEvents(int index, int& fd, int& events)
{
	fd = m_pEvents[index].data.fd;
	events = m_pEvents[index].events;
}
